home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / at.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  8KB  |  383 lines

  1. /*      Timed execution routine. Starts a timer and executes a sequence
  2.  *      of commands when expired.
  3.  *
  4.  *      Added by IW0CNB - Feb 1992
  5.  *  'at mm' format added by WG7J - 920805
  6.  *  
  7.  *      Added by WA7TAS Oct 1992:
  8.  *
  9.  *         Repeating AT command
  10.  *         'at k' command
  11.  *
  12.  */
  13. #include <stdio.h>
  14. #include <time.h>
  15. #ifdef MSDOS
  16. #include <dos.h>
  17. #endif
  18. #include "global.h"
  19. #include "timer.h"
  20. #include "cmdparse.h"
  21. #include "socket.h"
  22.  
  23. #ifdef UNIX
  24. #define mktime j_mktime
  25. #ifdef __cplusplus
  26. extern "C" {
  27. #endif
  28. extern time_t mktime __ARGS((struct tm *));
  29. #ifdef __cplusplus
  30. }
  31. #endif
  32. #endif
  33.  
  34. static void atcmd __ARGS((char *command));
  35. static void atproc __ARGS((int i,void *p1,void *p2));
  36.  
  37. /* List of events; We keep note of all timer processes generated by the 
  38.  * at command.
  39.  */
  40. struct at_list {
  41.     struct at_list *next;   /* Linked-list pointer */
  42.     struct timer *at_timer;
  43.     char   recur[10];       /* used in recursive 'at' commands*/
  44.     unsigned int id;        /* numerical 'id' of this 'at' */
  45. };
  46.  
  47. #define NULLATLIST      (struct at_list *)0
  48.  
  49. static struct at_list *Head_loe = NULLATLIST;   /* Head of List Of Events */
  50. static int id=1;                /* next 'at' assigned gets this number */
  51.  
  52. int
  53. #ifdef PROTOTYPES
  54. doat(int argc,char **argv,void *p)
  55. #else
  56. doat(argc,argv,p)
  57. int argc;
  58. char *argv[];
  59. void *p;
  60. #endif
  61. {
  62.     struct date *exp_date;
  63.     struct time *exp_time;
  64.     struct timer *t;
  65.  
  66.     char *cp;
  67.     unsigned int tid;
  68.     int i,notf;
  69.     time_t nowtime;
  70.     unsigned long time1;
  71.     struct tm tm;
  72.     extern struct timer *Timers;
  73.     struct at_list *loe,*pp;        /* List of events */
  74.     char *Errmsg = "Usage:\nat yymmddhhmm <cmd>\nat hhmm <cmd>\nat mm <cmd>\nat now+hhmm <cmd>\nat k <id num> <id num> ...\n";
  75.  
  76.     if(argc < 2){           /* Print list of pending at commands */
  77.         tputs("List of events:\n");
  78.  
  79.         for(t = Timers;t != NULLTIMER;t = t->next){
  80.            if(t->func == (void (*)__ARGS((void*)))atcmd){
  81.             loe=Head_loe;
  82.             while(loe!=NULLATLIST) {
  83.                 if(loe->at_timer == t) break;
  84.                 loe=loe->next;
  85.             }
  86.             time(&nowtime);
  87.             nowtime = (time_t)(read_timer(t) / 1000L + (unsigned long)nowtime);
  88.             cp = ctime(&nowtime);
  89.             rip(cp);
  90. #if 0
  91.             tprintf("At: %s - ID: %5u - Command: %s\n",cp,loe->id,t->arg);
  92. #endif
  93.             /* KF8NH: account for ID hidden at start of command */
  94.             tprintf("At: %s - ID: %5u - Command: %s\n",cp,loe->id,(char*)t->arg + sizeof loe->id);
  95.            }
  96.         }
  97.         return 0;
  98.     }
  99.  
  100.     if(argc < 3){
  101.         tputs(Errmsg);
  102.         return 0;
  103.     }
  104.  
  105.     if(argv[1][0]=='k') {
  106.        i=2;
  107.        while(i<argc) {
  108.         tid=atoi(argv[i]);
  109.         if(strlen(argv[i])>5 || tid==0 || atol(argv[i])>65535) {
  110.             tprintf("Invalid ID #.\n");
  111.             return 0;
  112.         }
  113.         loe=Head_loe;
  114.         notf=1;
  115. #ifdef __GNUC__
  116.         pp = 0;        /* silence warning */
  117. #endif
  118.         while(loe!=NULLATLIST) {
  119.             if(loe->id==tid) {
  120.                 stop_timer(loe->at_timer);
  121.         free(loe->at_timer->arg);
  122.         free(loe->at_timer);
  123.                 if(loe == Head_loe) {
  124.                     Head_loe=loe->next;
  125.                 }
  126.                 else {
  127.                     pp->next=loe->next;
  128.                 }
  129.                 free(loe);
  130.                 tprintf("at id: %u--Killed.\n",tid);
  131.                 notf=0;
  132.                 break;
  133.             }
  134.             pp=loe;
  135.             loe=loe->next;
  136.         }
  137.         if(notf) tprintf("  ID %u not found.\n",tid);
  138.         i++;
  139.         }
  140.         return 0;
  141.     }
  142.     exp_date = (struct date *)mallocw(sizeof(struct date));
  143.     exp_time = (struct time *)mallocw(sizeof(struct time));
  144.  
  145.     cp=mallocw(5);
  146.  
  147.     switch(strlen(argv[1])){
  148.        case 10:     /* Full date and time given */
  149.         cp[0]=argv[1][0];
  150.         cp[1]=argv[1][1];
  151.         cp[2]='\0';
  152.     
  153.         exp_date->da_year = 1900 + atoi(cp);
  154.         if(exp_date->da_year > 1999) goto error;
  155.  
  156.         cp[0]=argv[1][2];
  157.         cp[1]=argv[1][3];
  158.         cp[2]='\0';
  159.  
  160.         exp_date->da_mon = (char)atoi(cp);
  161.         if(exp_date->da_mon > 12) goto error;
  162.  
  163.         cp[0]=argv[1][4];
  164.         cp[1]=argv[1][5];
  165.         cp[2]='\0';
  166.  
  167.         exp_date->da_day = (char)atoi(cp);
  168.         if(exp_date->da_day > 31) goto error;
  169.  
  170.         cp[0]=argv[1][6];
  171.         cp[1]=argv[1][7];
  172.         cp[2]='\0';
  173.  
  174.         exp_time->ti_hour = (char)atoi(cp);
  175.         if(exp_time->ti_hour > 23) goto error;
  176.  
  177.         cp[0]=argv[1][8];
  178.         cp[1]=argv[1][9];
  179.         cp[2]='\0';
  180.  
  181.         exp_time->ti_min = (char)atoi(cp);
  182.         if(exp_time->ti_min > 59) goto error;
  183.  
  184.         exp_time->ti_sec = 0;
  185.         exp_time->ti_hund = 0;
  186.  
  187.         time(&nowtime);
  188.         time1 = (unsigned long)dostounix(exp_date,exp_time);
  189.         if(time1 < (unsigned long)nowtime) goto error;
  190.  
  191.         break;
  192.  
  193.        case 4:  /* Only time given, so apply current date */
  194.         getdate(exp_date);
  195.         cp[0]=argv[1][0];
  196.         cp[1]=argv[1][1];
  197.         cp[2]='\0';
  198.  
  199.         exp_time->ti_hour = (char)atoi(cp);
  200.         if(exp_time->ti_hour > 23) goto error;
  201.  
  202.         cp[0]=argv[1][2];
  203.         cp[1]=argv[1][3];
  204.         cp[2]='\0';
  205.  
  206.         exp_time->ti_min = (char)atoi(cp);
  207.         if(exp_time->ti_min > 59) goto error;
  208.  
  209.         exp_time->ti_sec = 0;
  210.         exp_time->ti_hund = 0;
  211.  
  212.         time(&nowtime);
  213.         time1 = (unsigned long)dostounix(exp_date,exp_time);
  214.         if(time1 <= (unsigned long)nowtime){ /* Requested time has passed */
  215.             time1 += 86400L;                /* So book him for tomorrow */
  216.         }
  217.         break;
  218.  
  219.  
  220.        case 2:  /* Only minutes given, so apply current time & date - WG7J */
  221.     tm.tm_min = (char)atoi(argv[1]);
  222.     if(tm.tm_min > 59) goto error;
  223.  
  224.     /* get today's date */
  225.         getdate(exp_date);
  226.     tm.tm_year = exp_date->da_year - 1900;
  227.     tm.tm_mday = exp_date->da_day;
  228.     tm.tm_mon = exp_date->da_mon - 1;
  229.  
  230.     /* get current time */
  231.     gettime(exp_time);
  232.     tm.tm_hour = exp_time->ti_hour;
  233.     /* if we're already past the minute, do it next hour ! */
  234.     if(exp_time->ti_min > tm.tm_min)
  235.         tm.tm_hour++;
  236.  
  237.     /* now adjust this for day boundaries, etc. */
  238.     tm.tm_sec = 0;
  239.     tm.tm_isdst = 0;
  240.     time1 = mktime(&tm);
  241.     time(&nowtime);
  242.     break;
  243.  
  244.        case 8:      /* now+hhmm given */
  245.         strncpy(cp,argv[1],4);
  246.         cp[4]='\0';
  247.         if(strcmp(cp,"now+") != 0) goto error;
  248.  
  249.         cp[0]=argv[1][4];
  250.         cp[1]=argv[1][5];
  251.         cp[2]='\0';
  252.  
  253.         time1=(unsigned long)atoi(cp)*3600L;
  254.  
  255.         cp[0]=argv[1][6];
  256.         cp[1]=argv[1][7];
  257.         cp[2]='\0';
  258.  
  259.         time1+=(unsigned long)atoi(cp)*60L;
  260.         time(&nowtime);
  261.         time1+=(unsigned long)nowtime;
  262.         break;
  263.  
  264.        default:
  265. error:          tprintf(Errmsg);
  266.         free(exp_date);
  267.         free(exp_time);
  268.         free(cp);
  269.     return 0;
  270.  
  271.     } /* switch */
  272.  
  273.     free(cp);
  274.     free(exp_time);
  275.     free(exp_date);
  276.  
  277.     t=(struct timer *)mallocw(sizeof(struct timer));
  278.  
  279.     set_timer(t,(int32)(time1 - (unsigned long)nowtime) * 1000L);
  280.     t->state=TIMER_RUN;
  281.     t->func=(void (*)__ARGS((void*)))atcmd;
  282.  
  283.     /* Add the new timer to the head of List Of Events */
  284.     loe=(struct at_list *)mallocw(sizeof(struct at_list));
  285.     loe->at_timer=t;
  286. /*
  287.  * if timer is recursive, set at_list->recur
  288.  */
  289.     loe->recur[0]=0;
  290.     if(argv[2][strlen(argv[2])-1] == '+') strcpy(loe->recur,argv[1]);
  291. /*
  292.  * an id of 0 is invalid
  293.  */
  294.     if(id==0) id=1;
  295.     loe->id=id++;
  296.     loe->next=Head_loe;
  297.     Head_loe=loe;
  298.  
  299.     /* KF8NH: save ID as well for atproc() (q.v.) */
  300.     /* (excessive use of sizeof() so this works for both of us...) */
  301.     t->arg = (char *) mallocw(strlen(argv[2]) + sizeof loe->id + 2);
  302.     memcpy(t->arg, &loe->id, sizeof loe->id);
  303.     strcpy(((char *) t->arg) + sizeof loe->id, argv[2]);
  304.     start_timer(t);
  305.  
  306.     return 0;
  307. }
  308.  
  309.  
  310. /* Process that actually handles 'at' execution */
  311. void
  312. atproc(int i,void *p1,void *p2) {
  313.     extern struct cmds far Cmds[];
  314.     char *command;
  315.     struct at_list *loe, *p;
  316.     int recur;
  317.     char *cmd;
  318.  
  319.     command =  (char *)p1;
  320.     cmd = malloc(strlen(command) + 20);
  321.  
  322.     log(-1,"AT command: %s",command);
  323.  
  324.     /* Free up memory for expired at commands */
  325.     p=Head_loe;
  326.     loe=Head_loe;
  327.     cmd[0] = '\0';
  328.     while(loe != NULLATLIST){
  329.     if (loe->id == i && loe->at_timer->state == TIMER_EXPIRE) {
  330.         strcpy(cmd,"at ");
  331.         strcat(cmd,loe->recur);
  332.         free(loe->at_timer);    /* Free timer */
  333.         if(loe == Head_loe){
  334.         Head_loe=loe->next;
  335.         p=loe->next;
  336.         free(loe);
  337.         loe=p;
  338.         p=Head_loe;
  339.         } else {
  340.         p->next=loe->next;
  341.         free(loe);
  342.         loe=p->next;
  343.         }
  344.         break;
  345.     }
  346.     if(loe != Head_loe) p=p->next;
  347.     loe=loe->next;
  348.     }
  349.     if (!*cmd)
  350.     where_outta_here(1);
  351.     if(command[strlen(command)-1] == '+') {
  352.     strcat(cmd," \"");
  353.     strcat(cmd,command);
  354.     strcat(cmd,"\"");
  355.     recur=1;
  356.     command[strlen(command)-1]=0;
  357.     }
  358.     else recur=0;
  359.  
  360.     cmdparse(Cmds,command,NULL);    /* Go with requested command */
  361.  
  362.     if(recur) {
  363.     cmdparse(Cmds,cmd,NULL);
  364.     }
  365.  
  366.     free(cmd);
  367.     free(p2);            /* correct... */
  368. }
  369.  
  370. /* Function to be called on timer expiration to execute a command */
  371. void
  372. atcmd(command)
  373. char *command;
  374. {
  375.     unsigned int id;        /* KF8NH: extracted for atproc check */
  376.     /* WARNING: the above must be precisely the same size as Head_loe->id */
  377.  
  378.     memcpy(&id, command, sizeof id);
  379.     newproc("AT handler", 1024, atproc, (int)id, (void *) (command + sizeof id),
  380.         command, 0);
  381. }
  382.  
  383.